Türkçe

React Context Selector Deseni ile yeniden oluşturmaları optimize edip performansı nasıl artıracağınızı öğrenin. Pratik örnekler ve en iyi uygulamalar içerir.

React Context Selector Deseni: Performans İçin Yeniden Oluşturmaları Optimize Etme

React Context API, uygulamalarınızdaki küresel durumu yönetmek için güçlü bir yol sunar. Ancak, Context kullanırken yaygın bir zorluk ortaya çıkar: gereksiz yeniden oluşturmalar (re-render). Context değeri değiştiğinde, o Context'i tüketen tüm bileşenler, Context verilerinin yalnızca küçük bir kısmına bağımlı olsalar bile yeniden oluşturulur. Bu, özellikle daha büyük ve daha karmaşık uygulamalarda performans darboğazlarına yol açabilir. Context Selector Deseni, bileşenlerin yalnızca ihtiyaç duydukları Context'in belirli kısımlarına abone olmalarını sağlayarak gereksiz yeniden oluşturmaları önemli ölçüde azaltan bir çözüm sunar.

Sorunu Anlamak: Gereksiz Yeniden Oluşturmalar

Bunu bir örnekle gösterelim. Kullanıcı bilgilerini (isim, e-posta, ülke, dil tercihi, sepet öğeleri) bir Context sağlayıcısında saklayan bir e-ticaret uygulaması hayal edin. Kullanıcı dil tercihini güncellerse, yalnızca kullanıcının adını görüntüleyenler de dahil olmak üzere Context'i tüketen tüm bileşenler yeniden oluşturulur. Bu verimsizdir ve kullanıcı deneyimini etkileyebilir. Farklı coğrafi konumlardaki kullanıcıları düşünün; Amerikalı bir kullanıcı profilini güncellerse, Avrupalı bir kullanıcının ayrıntılarını gösteren bir bileşen yeniden oluşturulmamalıdır.

Yeniden Oluşturmalar Neden Önemlidir

Context Selector Deseni ile Tanışın

Context Selector Deseni, bileşenlerin yalnızca ihtiyaç duydukları Context'in belirli kısımlarına abone olmalarını sağlayarak gereksiz yeniden oluşturma sorununu ele alır. Bu, Context değerinden gerekli verileri çıkaran bir seçici (selector) işlevi kullanılarak elde edilir. Context değeri değiştiğinde, React seçici işlevinin sonuçlarını karşılaştırır. Seçilen veri değişmediyse (katı eşitlik, === kullanarak), bileşen yeniden oluşturulmaz.

Nasıl Çalışır

  1. Context'i Tanımlayın: React.createContext() kullanarak bir React Context'i oluşturun.
  2. Bir Sağlayıcı (Provider) Oluşturun: Context değerini alt bileşenlerine sunmak için uygulamanızı veya ilgili bölümü bir Context Sağlayıcısı ile sarmalayın.
  3. Seçicileri (Selectors) Uygulayın: Context değerinden belirli verileri çıkaran seçici işlevleri tanımlayın. Bu işlevler saf (pure) olmalı ve yalnızca gerekli verileri döndürmelidir.
  4. Seçiciyi Kullanın: Seçilen veriyi almak ve yalnızca o verideki değişikliklere abone olmak için useContext ve seçici işlevinizden yararlanan özel bir hook (veya bir kütüphane) kullanın.

Context Selector Desenini Uygulama

Birçok kütüphane ve özel uygulama, Context Selector Deseni'ni kolaylaştırabilir. Özel bir hook kullanarak yaygın bir yaklaşımı inceleyelim.

Örnek: Basit bir Kullanıcı Context'i

Aşağıdaki yapıya sahip bir kullanıcı context'i düşünün:

const UserContext = React.createContext({ name: 'John Doe', email: 'john.doe@example.com', country: 'USA', language: 'en', theme: 'light' });

1. Context'i Oluşturma

const UserContext = React.createContext({ name: 'John Doe', email: 'john.doe@example.com', country: 'USA', language: 'en', theme: 'light' });

2. Sağlayıcıyı (Provider) Oluşturma

const UserProvider = ({ children }) => { const [user, setUser] = React.useState({ name: 'John Doe', email: 'john.doe@example.com', country: 'USA', language: 'en', theme: 'light' }); const updateUser = (updates) => { setUser(prevUser => ({ ...prevUser, ...updates })); }; const value = React.useMemo(() => ({ user, updateUser }), [user]); return ( {children} ); };

3. Seçici (Selector) ile Özel bir Hook Oluşturma

import React from 'react'; function useUserContext() { const context = React.useContext(UserContext); if (!context) { throw new Error('useUserContext must be used within a UserProvider'); } return context; } function useUserSelector(selector) { const context = useUserContext(); const [selected, setSelected] = React.useState(() => selector(context.user)); React.useEffect(() => { setSelected(selector(context.user)); // Initial selection const unsubscribe = context.updateUser; return () => {}; // No actual unsubscription needed in this simple example, see below for memoizing. }, [context.user, selector]); return selected; }

Önemli Not: Yukarıdaki `useEffect` uygun memoizasyondan yoksundur. `context.user` değiştiğinde, seçilen değer aynı olsa bile *her zaman* yeniden çalışır. Sağlam, memoize edilmiş bir seçici için sonraki bölüme veya `use-context-selector` gibi kütüphanelere bakın.

4. Seçici Hook'unu bir Bileşende Kullanma

function UserName() { const name = useUserSelector(user => user.name); return

Name: {name}

; } function UserEmail() { const email = useUserSelector(user => user.email); return

Email: {email}

; } function UserCountry() { const country = useUserSelector(user => user.country); return

Country: {country}

; }

Bu örnekte, UserName, UserEmail ve UserCountry bileşenleri yalnızca seçtikleri belirli veriler (sırasıyla isim, e-posta, ülke) değiştiğinde yeniden oluşturulur. Kullanıcının dil tercihi güncellenirse, bu bileşenler yeniden oluşturulmaz, bu da önemli performans iyileştirmeleri sağlar.

Seçicileri ve Değerleri Memoize Etme: Optimizasyon İçin Gerekli

Context Selector deseninin gerçekten etkili olabilmesi için memoizasyon çok önemlidir. Bu olmadan, seçici işlevler altta yatan veri anlamsal olarak değişmemiş olsa bile yeni nesneler veya diziler döndürebilir, bu da gereksiz yeniden oluşturmalara yol açar. Benzer şekilde, sağlayıcı değerinin de memoize edildiğinden emin olmak önemlidir.

Sağlayıcı Değerini useMemo ile Memoize Etme

useMemo kancası, UserContext.Provider'a iletilen değeri memoize etmek için kullanılabilir. Bu, sağlayıcı değerinin yalnızca altta yatan bağımlılıklar değiştiğinde değişmesini sağlar.

const UserProvider = ({ children }) => { const [user, setUser] = React.useState({ name: 'John Doe', email: 'john.doe@example.com', country: 'USA', language: 'en', theme: 'light' }); const updateUser = (updates) => { setUser(prevUser => ({ ...prevUser, ...updates })); }; // Memoize the value passed to the provider const value = React.useMemo(() => ({ user, updateUser }), [user, updateUser]); return ( {children} ); };

Seçicileri useCallback ile Memoize Etme

Seçici işlevleri bir bileşen içinde satır içi olarak tanımlanırsa, mantıksal olarak aynı olsalar bile her oluşturmada yeniden oluşturulurlar. Bu, Context Selector deseninin amacını boşa çıkarabilir. Bunu önlemek için, seçici işlevlerini memoize etmek üzere useCallback kancasını kullanın.

function UserName() { // Memoize the selector function const nameSelector = React.useCallback(user => user.name, []); const name = useUserSelector(nameSelector); return

Name: {name}

; }

Derin Karşılaştırma ve Değişmez Veri Yapıları

Context içindeki verilerin derinlemesine iç içe olduğu veya değiştirilebilir nesneler içerdiği daha karmaşık senaryolar için, değişmez veri yapıları (örneğin, Immutable.js, Immer) kullanmayı veya seçicinizde bir derin karşılaştırma işlevi uygulamayı düşünün. Bu, altta yatan nesneler yerinde değiştirilmiş olsa bile değişikliklerin doğru bir şekilde algılanmasını sağlar.

Context Selector Deseni için Kütüphaneler

Birçok kütüphane, Context Selector Deseni'ni uygulamak için hazır çözümler sunar, süreci basitleştirir ve ek özellikler sunar.

use-context-selector

use-context-selector, bu amaç için özel olarak tasarlanmış popüler ve iyi bakımlı bir kütüphanedir. Bir Context'ten belirli değerleri seçmek ve gereksiz yeniden oluşturmaları önlemek için basit ve etkili bir yol sunar.

Kurulum:

npm install use-context-selector

Kullanım:

import { useContextSelector } from 'use-context-selector'; function UserName() { const name = useContextSelector(UserContext, user => user.name); return

Name: {name}

; }

Valtio

Valtio, verimli durum güncellemeleri ve seçici yeniden oluşturmalar için proxy'leri kullanan daha kapsamlı bir durum yönetimi kütüphanesidir. Durum yönetimine farklı bir yaklaşım sunar ancak Context Selector Deseni ile benzer performans avantajları elde etmek için kullanılabilir.

Context Selector Deseninin Faydaları

Context Selector Deseni Ne Zaman Kullanılır

Context Selector Deseni özellikle aşağıdaki senaryolarda faydalıdır:

Context Selector Desenine Alternatifler

Context Selector Deseni güçlü bir araç olsa da, React'te yeniden oluşturmaları optimize etmek için tek çözüm değildir. İşte birkaç alternatif yaklaşım:

Küresel Uygulamalar için Dikkat Edilmesi Gerekenler

Küresel bir kitle için uygulamalar geliştirirken, Context Selector Deseni'ni uygularken aşağıdaki faktörleri göz önünde bulundurun:

Sonuç

React Context Selector Deseni, React uygulamalarında yeniden oluşturmaları optimize etmek ve performansı artırmak için değerli bir tekniktir. Bileşenlerin yalnızca ihtiyaç duydukları Context'in belirli kısımlarına abone olmalarını sağlayarak, gereksiz yeniden oluşturmaları önemli ölçüde azaltabilir ve daha duyarlı ve verimli bir kullanıcı arayüzü oluşturabilirsiniz. Maksimum optimizasyon için seçicilerinizi ve sağlayıcı değerlerinizi memoize etmeyi unutmayın. Uygulamayı basitleştirmek için use-context-selector gibi kütüphaneleri göz önünde bulundurun. Giderek daha karmaşık uygulamalar oluşturdukça, Context Selector Deseni gibi teknikleri anlamak ve kullanmak, performansı korumak ve özellikle küresel bir kitle için harika bir kullanıcı deneyimi sunmak için çok önemli olacaktır.